home *** CD-ROM | disk | FTP | other *** search
/ Sky at Night 2006 September / SAN CD 9-2006 CD-ROM 16.iso / pc / Software / Network Telescope Control / NTC-Setup.Exe / Source / ntc_ciel_client_form.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2006-03-24  |  23.7 KB  |  1,058 lines

  1. unit ntc_ciel_client_form;
  2. {
  3.     Copyright (C) 2004 - 2006 Andrew Sprott
  4.  
  5.     http://astronomy.crysania.co.uk
  6.     astro@trefach.co.uk
  7.  
  8.     This program is free software; you can redistribute it and/or
  9.     modify it under the terms of the GNU General Public License
  10.     as published by the Free Software Foundation; either version 2
  11.     of the License, or (at your option) any later version.
  12.  
  13.     This program is distributed in the hope that it will be useful,
  14.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16.     GNU General Public License for more details.
  17.  
  18.     You should have received a copy of the GNU General Public License
  19.     along with this program; if not, write to the Free Software
  20.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. }
  22.  
  23. interface
  24.  
  25. uses
  26.     Windows,
  27.     Messages,
  28.     SysUtils,
  29.     Classes,
  30.     Graphics,
  31.     Controls,
  32.     Forms,
  33.     Dialogs,
  34.     ShellAPI,
  35.     StdCtrls,
  36.     Buttons,
  37.     inifiles,
  38.     ComCtrls,
  39.     Menus,
  40.     ExtCtrls,
  41.     Mask,
  42.     ScktComp,
  43.  
  44.     ntc_ciel_client_button;
  45.  
  46. const
  47.     { network }
  48.     socket_number=8383;
  49.     { messages }
  50.     no_response='No response from server';
  51.     lost_connection='lost connection with server';
  52.     stop_error='NTC failed to stop the scope, '+
  53.                          'it could be that there is a error '+
  54.                          'or the network connection has failed';
  55.     { events }
  56.     event_0=0;
  57.     { scope types }
  58.     no_scope=0;
  59.     lx200_type=1;
  60.     autostar_type=2;
  61.     { interface }
  62.     button_width=57;
  63.     max_menu_items=10;
  64.  
  65. type
  66.     p_dimensions_record=^dimensions_record;
  67.     dimensions_record=record
  68.         vdu_index,
  69.         old_vdu_index,
  70.         screen_left,
  71.         screen_top,
  72.         last_screen_height,
  73.         last_screen_width,
  74.         current_height,
  75.         current_width,
  76.         form_top,
  77.         form_left:integer;
  78.     end;
  79.  
  80.     Tscope = class(TForm)
  81.     controller_pages: TPageControl;
  82.  
  83.         { constructors etc }
  84.         procedure formcreate(
  85.             Sender:TObject);
  86.  
  87.         procedure kill(
  88.                     Sender:TObject;
  89.             var CanClose:Boolean);
  90.  
  91.         { configuration backup }
  92.         procedure get_dimensions(
  93.             form:tform;
  94.             dimensions:p_dimensions_record;
  95.             section:string;
  96.             ini_file:tinifile);
  97.  
  98.         procedure write_dimensions(
  99.             dimensions:p_dimensions_record;
  100.             left,
  101.             top:integer;
  102.             section:string;
  103.             ini_file:tinifile);
  104.  
  105.         procedure load_settings;
  106.         procedure save_settings;
  107.  
  108.         { events }
  109.         procedure control_button_click(
  110.             Sender: TObject);
  111.  
  112.         procedure FormShow(
  113.             Sender: TObject);
  114.  
  115.         procedure hide_ntc(
  116.             Sender: TObject);
  117.  
  118.         procedure find_vdu(
  119.             form:tform;
  120.             dimensions:p_dimensions_record);
  121.  
  122.         procedure form_activate(
  123.             form:tform;
  124.             dimensions:p_dimensions_record);
  125.  
  126.         procedure check_activate(
  127.             Sender: TObject);
  128.  
  129.         procedure change_page;
  130.  
  131.         procedure page_change(
  132.             Sender: TObject);
  133.  
  134.         { menu item event handlers }
  135.         procedure sticky_handler(
  136.             sender:tobject);
  137.  
  138.         procedure buttonContextPopup(
  139.                     Sender: TObject;
  140.                     MousePos: TPoint;
  141.             var Handled: Boolean);
  142.  
  143.     private
  144.         { Private declarations }
  145.         previous_page,
  146.         current_page:ttabsheet;
  147.         active_page:integer;
  148.         { menu handling }
  149.         menu_items:array[1..max_menu_items] of TMenuItem;
  150.         context_menu:tpopupmenu;
  151.         im:integer;
  152.         { menu handler parameters }
  153.         button:tscope_button;
  154.  
  155.     public
  156.         { Public declarations }
  157.         { configuration }
  158.         dimensions:dimensions_record;
  159.  
  160.         { events }
  161.         procedure show_hide(
  162.             sender:tobject;
  163.             v:boolean);
  164.  
  165.     end;
  166.  
  167.     { ------------------------
  168.         Cartes du Ciel interface
  169.         ------------------------ }
  170.  
  171. Procedure ScopeShow; stdcall;
  172.  
  173. Procedure ScopeShowModal(
  174.     var ok:boolean); stdcall;
  175.  
  176. Procedure ScopeConnect(
  177.     var ok:boolean); stdcall;
  178.  
  179. Procedure ScopeDisconnect(
  180.     var ok:boolean); stdcall;
  181.  
  182. Procedure ScopeGetInfo(
  183.     var Name:shortstring;
  184.     var QueryOK,
  185.             SyncOK,
  186.             GotoOK:boolean;
  187.     var refreshrate:integer); stdcall;
  188.  
  189. Procedure ScopeSetObs(
  190.     la,
  191.     lo:double); stdcall;
  192.  
  193. Procedure ScopeAlign(
  194.     source:string;
  195.     ra,
  196.     dec:double); stdcall;
  197.  
  198. Procedure ScopeGetRaDec(
  199.     var ar,
  200.             de:double;
  201.     var ok:boolean); stdcall;
  202.  
  203. Procedure ScopeGetAltAz(
  204.     var alt,
  205.             az:double;
  206.     var ok:boolean); stdcall;
  207.  
  208. Procedure ScopeGoto(
  209.             ar,
  210.             de:double;
  211.     var ok:boolean); stdcall;
  212.  
  213. Procedure ScopeReset; stdcall;
  214.  
  215. Function ScopeInitialized:boolean ; stdcall;
  216.  
  217. Function ScopeConnected:boolean ; stdcall;
  218.  
  219. Procedure ScopeClose; stdcall;
  220.  
  221. procedure init_client;
  222.  
  223.     { ----------------
  224.         global variables
  225.         ---------------- }
  226.  
  227. var
  228.     scope:tscope;
  229.     application_path:string;
  230.     scope_type:word;
  231.     { configuration }
  232.     ini_file:tinifile;
  233.     max_width:integer;
  234.     ciel_closing:boolean;
  235.  
  236. implementation
  237.  
  238. uses
  239.     ntc_ciel_client_network,
  240.     ntc_ciel_client_control,
  241.     ntc_ciel_client_info,
  242.     ntc_ciel_client_focus,
  243.     ntc_ciel_client_tracking,
  244.     ntc_ciel_client_about,
  245.     ntc_ciel_client_search,
  246.     ntc_ciel_client_observer;
  247.  
  248. {$R *.DFM}
  249.  
  250.     { ------------
  251.         constructors
  252.         ------------ }
  253.  
  254. procedure tscope.formcreate(
  255.     Sender:TObject);
  256. begin
  257.     visible:=false;
  258.     formstyle:=fsstayontop;
  259.     ciel_closing:=false;
  260.     application_path:=extractfilepath(paramstr(0));
  261.     helpfile:=application_path+'\ntc.hlp';
  262.     scope_type:=autostar_type;
  263.     previous_page:=nil;
  264.     load_settings;
  265.     controller_pages.activepage:=current_page;
  266. end;
  267.  
  268. procedure tscope.kill(
  269.             Sender:TObject;
  270.     var CanClose:Boolean);
  271. begin
  272.     if ciel_closing then
  273.         canclose:=true
  274.     else
  275.         canclose:=false;
  276. end;
  277.  
  278. procedure init_client;
  279. begin
  280.     Application.HelpFile:='ntc.hlp';
  281.     Application.Title := 'NTC Client for Cartes du Ciel';
  282.     scope.FormStyle:=fsNormal;
  283. end;
  284.  
  285.     { ------------------------
  286.         Cartes Du Ciel interface
  287.         ------------------------ }
  288.  
  289. Procedure ScopeConnect(
  290.     var ok:boolean); stdcall;
  291. begin
  292.     ok:=scope_control.connect_to_scope;
  293. end;
  294.  
  295. Procedure ScopeDisconnect(
  296.     var ok:boolean); stdcall;
  297. begin
  298.     scope.save_settings;
  299.     ok:=scope_control.disconnect_from_scope;
  300.     scope_network.kill;
  301. end;
  302.  
  303. Procedure ScopeClose; stdcall;
  304. begin
  305.     scope.save_settings;
  306.     ciel_closing:=true;
  307.     scope_control.release;
  308.     scope_search.release;
  309.     scope_focus.release;
  310.     scope_tracking.release;
  311.     scope_info.release;
  312.     scope_network.release;
  313.     scope_observer.release;
  314.     scope_about.release;
  315.     scope.release;
  316. end;
  317.  
  318. Function ScopeConnected
  319.     :boolean ; stdcall;
  320. begin
  321.     result:=scope_network.connected;
  322. end;
  323.  
  324. Function ScopeInitialized
  325.     :boolean ; stdcall;
  326. begin
  327.     result:=ScopeConnected;
  328. end;
  329.  
  330. Procedure ScopeAlign(
  331.     source:string;
  332.     ra,
  333.     dec:double); stdcall;
  334. begin
  335.     scope_network.send_request_check(
  336.         'align'+'(ra='+floattostr(ra)+',dec='+floattostr(dec)+')');
  337. end;
  338.  
  339. Procedure ScopeShowModal(
  340.     var ok:boolean); stdcall;
  341. begin
  342.     scope.showmodal;
  343.     ok:=(scope.modalresult=mrOK);
  344. end;
  345.  
  346. Procedure ScopeShow; stdcall;
  347. var
  348.     current:ttabsheet;
  349.     i:integer;
  350. begin
  351.     current:=scope.current_page;
  352.     with current do
  353.          for i:=0 to controlcount-1 do
  354.          with tscope_button(controls[i]) do
  355.          if not button_hidden then
  356.         case control_type of
  357.             s_info:scope_info.show_form;
  358.             s_about:scope_about.show_form;
  359.             s_focus:scope_focus.show_form;
  360.             s_network:scope_network.show_form;
  361.             s_search:scope_search.show_form;
  362.             s_control:scope_control.show_form;
  363.             s_tracking:scope_tracking.show_form;
  364.             s_observer:scope_observer.show_form;
  365.         end;
  366.     scope.show;
  367. end;
  368.  
  369. Procedure ScopeGetRaDec(
  370.     var ar,
  371.             de:double;
  372.     var ok:boolean); stdcall;
  373. begin
  374.     if ScopeConnected then
  375.          with scope_network do
  376.          if (send_request_check('get_ra_dec')=[exit_ok]) and
  377.             get_float('ra',ar) and
  378.             get_float('dec',de) then
  379.         ok:=true
  380.     else
  381.         ok:=false;
  382. end;
  383.  
  384. Procedure ScopeGetAltAz(
  385.     var alt,
  386.             az:double;
  387.     var ok:boolean); stdcall;
  388. begin
  389.     if ScopeConnected then
  390.          with scope_network do
  391.          if (send_request_check('get_az_alt')=[exit_ok]) and
  392.             get_float('az',az) and
  393.             get_float('alt',alt) then
  394.         ok:=true
  395.     else
  396.         ok:=false;
  397. end;
  398.  
  399. Procedure ScopeGetInfo(
  400.     var Name:shortstring;
  401.     var QueryOK,
  402.             SyncOK,
  403.             GotoOK:boolean;
  404.     var refreshrate:integer); stdcall;
  405. var
  406.     s:string;
  407. begin
  408.     queryok:=true;
  409.     gotook:=false;
  410.     syncok:=false;
  411.     if scope=nil then
  412.         scope:=Tscope.Create(nil);
  413.     with scope_network,scope_control,scope_focus,scope_tracking do
  414.          if (send_request_check('get_info')=[exit_ok]) and
  415.                 get_string('name',s) and
  416.                 get_boolean('can_goto',gotook) and
  417.                 get_boolean('can_sync',syncok) and
  418.                 get_boolean('can_focus',can_focus) and
  419.                 ((can_focus and get_integer('focus_speeds',focus_speeds)) or
  420.                  not can_focus) and
  421.                 get_boolean('can_track',can_track) then
  422.         begin
  423.             name:=shortstring(s);
  424.             refreshrate:=scope_info.controller_timer.Interval;
  425.             scope_name:=name;
  426.         end
  427.     else
  428.         begin
  429.             name:='';
  430.             refreshrate:=500;
  431.             scope_name:='unknown scope';
  432.         end;
  433. end;
  434.  
  435. Procedure ScopeReset; stdcall;
  436. begin
  437. end;
  438.  
  439. Procedure ScopeSetObs(
  440.     la,
  441.     lo:double); stdcall;
  442. begin
  443. end;
  444.  
  445. Procedure ScopeGoto(
  446.             ar,
  447.             de:double;
  448.     var ok:boolean); stdcall;
  449. begin
  450.     ok:=scope_network.send_request_check(
  451.         'goto_ra_dec'+'(ra='+floattostr(ar)+',dec='+floattostr(de)+')')>=[exit_ok];
  452. end;
  453.  
  454.     { --------------------
  455.         configuration backup
  456.         -------------------- }
  457.  
  458. procedure tscope.hide_ntc(
  459.     Sender: TObject);
  460. var
  461.     current:ttabsheet;
  462.     i:integer;
  463. begin
  464.     current:=scope.current_page;
  465.     with current do
  466.          for i:=0 to controlcount-1 do
  467.          with tscope_button(controls[i]) do
  468.          if not button_hidden then
  469.         case control_type of
  470.             s_info:scope_info.hide_form;
  471.             s_about:scope_about.hide_form;
  472.             s_focus:scope_focus.hide_form;
  473.             s_network:scope_network.hide_form;
  474.             s_search:scope_search.hide_form;
  475.             s_control:scope_control.hide_form;
  476.             s_tracking:scope_tracking.hide_form;
  477.             s_observer:scope_observer.hide_form;
  478.         end;
  479.     scope.Hide;
  480. end;
  481.  
  482. procedure Tscope.find_vdu(
  483.     form:tform;
  484.     dimensions:p_dimensions_record);
  485. var
  486.     i,lw,lh:integer;
  487.     done,vdu_changed:boolean;
  488.  
  489.     procedure switch_monitor;
  490.     begin
  491.         with dimensions^,screen.monitors[vdu_index] do
  492.             begin
  493.                 if screen_left<0 then
  494.                     begin
  495.                         if form_left>=0 then
  496.                             form_left:=form_left+screen_left+left
  497.                         else
  498.                             form_left:=abs(form_left-screen_left)+left;
  499.                     end
  500.                 else
  501.                     form_left:=form_left-screen_left+left;
  502.                 if screen_top<0 then
  503.                     begin
  504.                         if form_top>=0 then
  505.                             form_top:=form_top+screen_top+top
  506.                         else
  507.                             form_top:=abs(form_top-screen_top)+top;
  508.                     end
  509.                 else
  510.                     form_top:=form_top-screen_top+top;
  511.                 screen_left:=left;
  512.                 screen_top:=top;
  513.             end;
  514.     end;
  515.  
  516. begin
  517.     with screen,dimensions^ do
  518.         begin
  519.             vdu_changed:=false;
  520.             if vdu_index>=0 then
  521.                 begin
  522.                     i:=0;
  523.                     if (old_vdu_index>=0) and (old_vdu_index<monitorcount) then
  524.                         begin
  525.                             if old_vdu_index<>vdu_index then
  526.                                 begin
  527.                                     vdu_index:=old_vdu_index;
  528.                                     switch_monitor;
  529.                                 end;
  530.                             old_vdu_index:=-1;
  531.                         end;
  532.                     done:=false;
  533.                     while not done do
  534.                          if i<monitorcount then
  535.                          with monitors[i] do
  536.                         begin
  537.                             if (form_left<left) or
  538.                                  (form_left>left+width) or
  539.                                  (form_top<top) or
  540.                                  (form_top>top+height) then
  541.                                 inc(i)
  542.                             else
  543.                                 begin
  544.                                     if i<>vdu_index then
  545.                                         vdu_index:=i;
  546.                                     done:=true;
  547.                                 end;
  548.                         end
  549.                     else
  550.                         begin
  551.                             done:=true;
  552.                             vdu_changed:=true;
  553.                             vdu_index:=-1;
  554.                         end;
  555.                 end;
  556.             if vdu_index<0 then
  557.                 begin
  558.                     i:=0;
  559.                     while (i<monitorcount) and not monitors[i].Primary do
  560.                         inc(i);
  561.                     if i<monitorcount then
  562.                         vdu_index:=i
  563.                     else
  564.                         vdu_index:=0;
  565.                     vdu_changed:=true;
  566.                 end;
  567.             with monitors[vdu_index] do
  568.                 begin
  569.                     if vdu_changed then
  570.                         switch_monitor;
  571.                     lw:=current_width;
  572.                     lh:=current_height;
  573.                     if (lw<>width) or (lh<>height) then
  574.                         begin
  575.                             current_width:=width;
  576.                             current_height:=height;
  577.                             form_left:=trunc(form_left/last_screen_width*current_width);
  578.                             if form_left+form.width>left+current_width then
  579.                                 form_left:=left+current_width-form.Width;
  580.                             if form_left<left then
  581.                                 form_left:=left;
  582.                             form_top:=trunc(form_top/last_screen_height*current_height);
  583.                             if form_top+form.height>top+current_height then
  584.                                 form_top:=top+current_height-form.height;
  585.                             if form_top<top then
  586.                                 form_top:=top;
  587.                             last_screen_width:=current_width;
  588.                             last_screen_height:=current_height;
  589.                         end
  590.                     else
  591.                         begin
  592.                             current_width:=width;
  593.                             current_height:=height;
  594.                         end;
  595.                 end;
  596.         end;
  597. end;
  598.  
  599. procedure tscope.get_dimensions(
  600.     form:tform;
  601.     dimensions:p_dimensions_record;
  602.     section:string;
  603.     ini_file:tinifile);
  604. begin
  605.     with ini_file,dimensions^ do
  606.         begin
  607.             vdu_index:=readinteger(section,'monitor',-1);
  608.             old_vdu_index:=readinteger(section,'another_monitor',-1);
  609.             form_top:=readinteger(section,'top',form_top);
  610.             form_left:=readinteger(section,'left',form_left);
  611.             screen_left:=readinteger(section,'screen_left',0);
  612.             screen_top:=readinteger(section,'screen_top',0);
  613.             last_screen_width:=readinteger(section,'screen_width',-1);
  614.             current_width:=last_screen_width;
  615.             last_screen_height:=readinteger(section,'screen_height',-1);
  616.             current_height:=last_screen_height;
  617.             find_vdu(form,dimensions);
  618.         end;
  619. end;
  620.  
  621. procedure tscope.write_dimensions(
  622.     dimensions:p_dimensions_record;
  623.     left,
  624.     top:integer;
  625.     section:string;
  626.     ini_file:tinifile);
  627. var
  628.     i:integer;
  629. begin
  630.     with ini_file,screen,dimensions^ do
  631.         begin
  632.             for i:=0 to monitorcount-1 do
  633.                  if monitors[i].primary and (vdu_index<>i) then
  634.                 old_vdu_index:=vdu_index;
  635.             writeinteger(section,'another_monitor',old_vdu_index);
  636.             writeinteger(section,'monitor',vdu_index);
  637.             writeinteger(section,'left',left);
  638.             writeinteger(section,'top',top);
  639.             writeinteger(section,'screen_width',current_width);
  640.             writeinteger(section,'screen_height',current_height);
  641.             writeinteger(section,'screen_left',monitors[vdu_index].left);
  642.             writeinteger(section,'screen_top',monitors[vdu_index].top);
  643.         end;
  644. end;
  645.  
  646. procedure tscope.load_settings;
  647. var
  648.     l,m,ip,ib,t:integer;
  649.     p,b,bn:string;
  650.     pd,bd,h,s:boolean;
  651.     ts:ttabsheet;
  652.  
  653.     procedure add_control_page(
  654.         page_name:string);
  655.     begin
  656.         with controller_pages do
  657.             begin
  658.                 ts:=ttabsheet.create(self);
  659.                 with ts do
  660.                     begin
  661.                         pagecontrol:=controller_pages;
  662.                         caption:=page_name;
  663.                         l:=0;
  664.                     end;
  665.             end;
  666.     end;
  667.  
  668.     procedure add_button(
  669.         scope_control_object:scope_button_type;
  670.         button_name:string;
  671.         hidden,
  672.         stuck:boolean);
  673.     begin
  674.         with ts,tscope_button.create(ts) do
  675.             begin
  676.                 visible:=false;
  677.                 caption:=button_name;
  678.                 left:=l;
  679.                 width:=button_width;
  680.                 inc(l,button_width);
  681.                 if l>m then
  682.                     m:=l;
  683.                 top:=0;
  684.                 height:=25;
  685.                 parent:=ts;
  686.                 button_hidden:=hidden;
  687.                 if button_hidden then
  688.                     button_stuck:=false
  689.                 else
  690.                     begin
  691.                         button_stuck:=stuck;
  692.                         if stuck then
  693.                             font.style:=[fsbold]
  694.                         else
  695.                             font.style:=[];
  696.                     end;
  697.                 control_type:=scope_control_object;
  698.                 onclick:=control_button_click;
  699.                 oncontextpopup:=buttonContextPopup;
  700.                 visible:=true;
  701.             end;
  702.     end;
  703.  
  704.     procedure add_hide_button;
  705.     begin
  706.         with ts,tscope_button.create(ts) do
  707.             begin
  708.                 visible:=false;
  709.                 caption:='Hide';
  710.                 left:=l;
  711.                 width:=button_width;
  712.                 inc(l,button_width);
  713.                 if l>m then
  714.                     m:=l;
  715.                 top:=0;
  716.                 height:=25;
  717.                 parent:=ts;
  718.                 font.style:=[];
  719.                 onclick:=hide_ntc;
  720.                 visible:=true;
  721.             end;
  722.     end;
  723.  
  724.     procedure add_menu(
  725.         i:integer;
  726.         s:string;
  727.         h:tnotifyevent);
  728.     begin
  729.         if im>max_menu_items then
  730.             scope_network.write_status_log_check('too many menus : '+inttostr(im))
  731.         else
  732.             begin
  733.                 menu_items[im]:=nil;
  734.                 menu_items[im]:=tmenuitem.create(self);
  735.                 with menu_items[im] do
  736.                     begin
  737.                         caption:=s;
  738.                         checked:=false;
  739.                         onclick:=h;
  740.                     end;
  741.                 context_menu.items.add(menu_items[im]);
  742.             end;
  743.         inc(im);
  744.     end;
  745.  
  746. begin
  747.     ini_file:=tinifile.create(application_path+'ciel.ini');
  748.     scope_type:=ini_file.ReadInteger('main','scope_type',autostar_type);
  749.     { menus }
  750.     context_menu:=tpopupmenu.create(self);
  751.     im:=1;
  752.     add_menu(im,'Sticky Control',sticky_handler);
  753.     { control panel }
  754.     m:=0;
  755.     current_page:=nil;
  756.     with controller_pages,ini_file do
  757.          if readinteger('main','num_control_panels',0)>0 then
  758.         begin
  759.             active_page:=readinteger('main','active_page',0);
  760.             ip:=1;
  761.             pd:=false;
  762.             while not pd do
  763.                 begin
  764.                     p:=readstring('main','panel_'+inttostr(ip),'');
  765.                     if p<>'' then
  766.                         begin
  767.                             add_control_page(p);
  768.                             if active_page=ip then
  769.                                 current_page:=ts;
  770.                             p:='panel_'+inttostr(ip);
  771.                             ib:=1;
  772.                             bd:=false;
  773.                             while not bd do
  774.                                 begin
  775.                                     b:='button_'+inttostr(ib)+'_';
  776.                                     bn:=readstring(p,b+'name','');
  777.                                     if bn<>'' then
  778.                                         begin
  779.                                             t:=readinteger(p,b+'module',0);
  780.                                             h:=readbool(p,b+'hidden',true);
  781.                                             s:=readbool(p,b+'stuck',false);
  782.                                             if t>0 then
  783.                                                 begin
  784.                                                     case t of
  785.                                                         s_info:add_button(s_info,bn,h,s);
  786.                                                         s_focus:add_button(s_focus,bn,h,s);
  787.                                                         s_about:add_button(s_about,bn,h,s);
  788.                                                         s_object:add_button(s_object,bn,h,s);
  789.                                                         s_search:add_button(s_search,bn,h,s);
  790.                                                         s_control:add_button(s_control,bn,h,s);
  791.                                                         s_network:add_button(s_network,bn,h,s);
  792.                                                         s_tracking:add_button(s_tracking,bn,h,s);
  793.                                                         s_observer:add_button(s_observer,bn,h,s);
  794.                                                     end;
  795.                                                 end;
  796.                                         end
  797.                                     else
  798.                                         bd:=true;
  799.                                     inc(ib);
  800.                                 end;
  801.                             add_hide_button;
  802.                         end
  803.                     else
  804.                         pd:=true;
  805.                     inc(ip);
  806.                 end;
  807.             if current_page=nil then
  808.                 begin
  809.                     current_page:=controller_pages.activepage;
  810.                     active_page:=controller_pages.ActivePageIndex+1;
  811.                 end
  812.             else
  813.                 controller_pages.activepage:=current_page;
  814.         end
  815.     else
  816.         begin
  817.             add_control_page('Setup');
  818.             add_button(s_about,'About',true,false);
  819.             add_button(s_network,'Network',true,false);
  820.             add_button(s_observer,'Location',true,false);
  821.             add_hide_button;
  822.             add_control_page('Control');
  823.             add_button(s_info,'Info',true,false);
  824.             add_button(s_focus,'Focus',true,false);
  825.             add_button(s_search,'Search',true,false);
  826.             add_button(s_control,'Control',true,false);
  827.             add_button(s_tracking,'Track',true,false);
  828.             add_hide_button;
  829.             current_page:=controller_pages.ActivePage;
  830.             active_page:=controller_pages.ActivePageIndex+1;
  831.         end;
  832.     max_width:=m;
  833.     { form }
  834.     get_dimensions(scope,@dimensions,'main',ini_file);
  835.     ini_file.Free;
  836. end;
  837.  
  838. procedure tscope.save_settings;
  839. var
  840.     i,j:integer;
  841.     ps,bs:string;
  842. begin
  843.     ini_file:=tinifile.create(application_path+'ciel.ini');
  844.     scope_network.save_settings;
  845.     scope_control.save_settings;
  846.     scope_focus.save_settings;
  847.     scope_info.save_settings;
  848.     scope_tracking.save_settings;
  849.     scope_search.save_settings;
  850.     scope_observer.save_settings;
  851.     scope_about.save_settings;
  852.     with ini_file do
  853.         begin
  854.             { control panel }
  855.             with controller_pages do
  856.                 begin
  857.                     for i:=0 to pagecount-1 do
  858.                         begin
  859.                             ps:='panel_'+inttostr(i+1);
  860.                             writestring('main',ps,pages[i].caption);
  861.                             for j:=0 to pages[i].ControlCount-1 do
  862.                                  with pages[i],tscope_button(Controls[j]) do
  863.                                 begin
  864.                                     bs:='button_'+inttostr(j+1)+'_';
  865.                                     WriteString(ps,bs+'name',caption);
  866.                                     writestring(ps,bs+'module',inttostr(control_type));
  867.                                     writebool(ps,bs+'hidden',button_hidden);
  868.                                     writebool(ps,bs+'stuck',button_stuck);
  869.                                 end;
  870.                         end;
  871.                     writestring('main','num_control_panels',inttostr(pagecount));
  872.                 end;
  873.             writeinteger('main','active_page',active_page);
  874.             { form }
  875.             find_vdu(scope,@dimensions);
  876.             write_dimensions(@dimensions,left,top,'main',ini_file);
  877.         end;
  878.     ini_file.free;
  879. end;
  880.  
  881.     { ------
  882.         events
  883.         ------ }
  884.  
  885. procedure Tscope.FormShow(
  886.     Sender: TObject);
  887. begin
  888.     with dimensions do
  889.         begin
  890.             top:=form_top;
  891.             left:=form_left;
  892.             clientwidth:=max_width;
  893.         end;
  894.     change_page;
  895. end;
  896.  
  897. procedure Tscope.form_activate(
  898.     form:tform;
  899.     dimensions:p_dimensions_record);
  900. var
  901.     w,h:integer;
  902. begin
  903.     with form,dimensions^ do
  904.         begin
  905.             find_vdu(form,dimensions);
  906.             w:=screen.monitors[vdu_index].width;
  907.             h:=screen.monitors[vdu_index].Height;
  908.             if (w<>current_width) or
  909.                  (h<>current_height) then
  910.                 begin
  911.                     last_screen_width:=current_width;
  912.                     last_screen_height:=current_height;
  913.                     current_width:=w;
  914.                     current_height:=h;
  915.                     scope_network.adjust;
  916.                     scope_control.adjust;
  917.                     scope_about.adjust;
  918.                     scope_focus.adjust;
  919.                     scope_info.adjust;
  920.                     scope_observer.adjust;
  921.                     scope_tracking.adjust;
  922.                     scope_search.adjust;
  923.                     form_top:=trunc(form_top/last_screen_height*current_height);
  924.                     form_left:=trunc(form_left/last_screen_width*current_width);
  925.                     top:=form_top;
  926.                     left:=form_left;
  927.                     scope.show;
  928.                 end;
  929.         end;
  930. end;
  931.  
  932. procedure Tscope.check_activate(
  933.     Sender: TObject);
  934. begin
  935.     form_activate(scope,@dimensions);
  936. end;
  937.  
  938. procedure Tscope.show_hide(
  939.     sender:tobject;
  940.     v:boolean);
  941. begin
  942.     with tscope_button(sender) do
  943.          if not v then
  944.         begin
  945.             if button_stuck then
  946.                 font.style:=[];
  947.             button_stuck:=false;
  948.             button_hidden:=true;
  949.         end
  950.     else
  951.         button_hidden:=false;
  952. end;
  953.  
  954. procedure Tscope.control_button_click(
  955.     Sender: TObject);
  956. begin
  957.     with tscope_button(sender) do
  958.         begin
  959.             case control_type of
  960.                 s_info:scope_info.check_visible_and_show_hide(sender);
  961.                 s_focus:scope_focus.check_visible_and_show_hide(sender);
  962.                 s_about:scope_about.check_visible_and_show_hide(sender);
  963.                 s_network:scope_network.check_visible_and_show_hide(sender);
  964.                 s_search:scope_search.check_visible_and_show_hide(sender);
  965.                 s_control:scope_control.check_visible_and_show_hide(sender);
  966.                 s_tracking:scope_tracking.check_visible_and_show_hide(sender);
  967.                 s_observer:scope_observer.check_visible_and_show_hide(sender);
  968.             end;
  969.         end;
  970. end;
  971.  
  972. procedure tscope.change_page;
  973. var
  974.     i:integer;
  975. begin
  976.     previous_page:=current_page;
  977.     if previous_page<>nil then
  978.          with previous_page do
  979.          for i:=0 to controlcount-1 do
  980.          with tscope_button(controls[i]) do
  981.         begin
  982.             if not button_stuck then
  983.                  case control_type of
  984.                 s_info:scope_info.hide_form;
  985.                 s_about:scope_about.hide_form;
  986.                 s_focus:scope_focus.hide_form;
  987.                 s_network:scope_network.hide_form;
  988.                 s_search:scope_search.hide_form;
  989.                 s_control:scope_control.hide_form;
  990.                 s_tracking:scope_tracking.hide_form;
  991.                 s_observer:scope_observer.hide_form;
  992.             end;
  993.         end;
  994.     current_page:=controller_pages.ActivePage;
  995.     with current_page do
  996.          for i:=0 to controlcount-1 do
  997.          with tscope_button(controls[i]) do
  998.         begin
  999.             if not button_hidden then
  1000.                  case control_type of
  1001.                 s_info:scope_info.show_form;
  1002.                 s_about:scope_about.show_form;
  1003.                 s_focus:scope_focus.show_form;
  1004.                 s_network:scope_network.show_form;
  1005.                 s_search:scope_search.show_form;
  1006.                 s_control:scope_control.show_form;
  1007.                 s_tracking:scope_tracking.show_form;
  1008.                 s_observer:scope_observer.show_form;
  1009.             end;
  1010.         end;
  1011.     active_page:=controller_pages.ActivePageIndex+1;
  1012. end;
  1013.  
  1014. procedure Tscope.page_change(
  1015.     Sender: TObject);
  1016. begin
  1017.     change_page;
  1018. end;
  1019.  
  1020.     { -------------------
  1021.         menu event handlers
  1022.         ------------------- }
  1023.  
  1024. { menu handlers }
  1025. procedure tscope.sticky_handler(
  1026.     sender:tobject);
  1027. begin
  1028.     with tmenuitem(sender) do
  1029.         begin
  1030.             with button do
  1031.                 begin
  1032.                     button_stuck:=not button_stuck;
  1033.                     if button_stuck then
  1034.                         font.Style:=[fsbold]
  1035.                     else
  1036.                         font.style:=[];
  1037.                 end;
  1038.         end;
  1039. end;
  1040.  
  1041. procedure tscope.buttonContextPopup(
  1042.             Sender: TObject;
  1043.             MousePos: TPoint;
  1044.     var Handled: Boolean);
  1045. begin
  1046.     { setup up parameters }
  1047.     button:=sender as tscope_button;
  1048.     { call popup menu }
  1049.     handled:=true;
  1050.     with button do
  1051.          context_menu.popup(
  1052.         scope.left+current_page.left+parent.left+left+mousepos.x,
  1053.         scope.top+current_page.top+parent.top+top+mousepos.y);
  1054. end;
  1055.  
  1056. end.
  1057.  
  1058.